package org.apache.james.imap.server;

import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

import org.apache.james.services.FileSystem;

public class SSLConfiguration {
	String keystoreURL;
	String keystorePassword;
	String keyPassword;
	String provider = "SunX509";
	String keystoreFormat = "JKS";
	String protocol = "TLSv1";
	
	SSLContext context;
	
	
	FileSystem fileSystem;
	
	
	
	
	public void setKeystoreURL(String keystoreURL) {
		this.keystoreURL = keystoreURL;
	}


	public void setKeystorePassword(String keystorePassword) {
		this.keystorePassword = keystorePassword;
	}


	public void setKeyPassword(String keyPassword) {
		this.keyPassword = keyPassword;
	}


	public void setProvider(String provider) {
		this.provider = provider;
	}


	public void setKeystoreFormat(String keystoreFormat) {
		this.keystoreFormat = keystoreFormat;
	}


	public void setProtocol(String protocol) {
		this.protocol = protocol;
	}


	public void setFileSystem(FileSystem fileSystem) {
		this.fileSystem = fileSystem;
	}


	public synchronized SSLContext getContext() throws GeneralSecurityException, IOException {
		if (context==null) {
			context = createContext(fileSystem.getResource(keystoreURL));
		}
		return context;
	}

	
	private SSLContext createContext(InputStream keystoreStream) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException, KeyManagementException {
		
		  KeyStore keystore = KeyStore.getInstance( keystoreFormat );
	
		  keystore.load(keystoreStream, keystorePassword!=null ? keystorePassword.toCharArray() : null);
		  
		  KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(provider);
		  
		  keyManagerFactory.init(keystore, keyPassword.toCharArray());
		  
		  TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(provider);
		  
		  trustManagerFactory.init(keystore);
		  
		  SSLContext sslContext = SSLContext.getInstance(protocol);
		  
		  sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
		  
		  return sslContext;		  
	}
	
}
